package com.wx.token;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.wx.service.CoreService;
import com.wx.util.SignUtil;
import com.wx.util.TokenUtil;

@Controller
@RequestMapping("/sz")
public class TokenController {
	private Logger log = LoggerFactory.getLogger(TokenController.class);
	private static TokenTimeOut tokenTimeOut = new TokenTimeOut();

	@ResponseBody
	@RequestMapping(value = "/action", method = RequestMethod.GET)
	public String checkSignature(HttpServletRequest request, String signature,
			String timestamp, String nonce, String echostr)
			throws JsonParseException, JsonMappingException, IOException {
		// 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
			log.debug(echostr);
			return echostr;
		} else {
			System.out.println("不是微信服务器发来的请求,请小心!");
			return null;
		}
	}

	@ResponseBody
	@RequestMapping(value = "/action", method = RequestMethod.POST)
	public String action(HttpServletRequest request,HttpServletResponse response)
			throws JsonParseException, JsonMappingException, IOException {
		if (!tokenTimeOut.isAlive()) {
			AccessToken accessToken = TokenUtil.getAccessToken();
			request.getSession().getServletContext()
					.setAttribute("accessToken", accessToken);
			tokenTimeOut.setServletContext(request.getSession()
					.getServletContext());
			tokenTimeOut.setDaemon(true);
			tokenTimeOut.start();
			log.debug("accessToken: "+accessToken.getAccess_token());
		}
		// 将请求、响应的编码均设置为UTF-8（防止中文乱码）  
        request.setCharacterEncoding("UTF-8");  //微信服务器POST消息时用的是UTF-8编码，在接收时也要用同样的编码，否则中文会乱码；
        response.setCharacterEncoding("UTF-8"); //在响应消息（回复消息给用户）时，也将编码方式设置为UTF-8，原理同上；
        //初始化配置文件
        String respMessage = CoreService.processRequest(request);//调用CoreService类的processRequest方法接收、处理消息，并得到处理结果；
        System.out.println(respMessage);
        // 响应消息  
        //调用response.getWriter().write()方法将消息的处理结果返回给用户
        return respMessage;
	}
	
}

/**
 * 检测accessToken是否超时
 * @author su
 * 
 */
class TokenTimeOut extends Thread {
	private Logger log = LoggerFactory.getLogger(TokenTimeOut.class);
	private ServletContext servletContext;
	private static int expires_in = 0;
	private static StopWatch watch = new StopWatch();

	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	@Override
	public void run() {
		expires_in = ((AccessToken) servletContext.getAttribute("accessToken"))
				.getExpires_in();
		while (true) {
			watch.start(); 
			long diff = watch.getTime()/1000;
			if (diff >= (expires_in-200)) {
				log.info("accessToken即将超时，重新获取");
				try {
					AccessToken accessToken = TokenUtil.getAccessToken();
					servletContext.removeAttribute("accessToken");
					servletContext.setAttribute("accessToken", accessToken);
					expires_in = accessToken.getExpires_in();
					watch.reset();
					watch.start(); 
				} catch (Exception e) {
					e.printStackTrace();
					log.error(e.getMessage());
				}
			} else {
				try {
					log.debug("accessToken线程休眠：" + 10 + "秒");
					Thread.sleep(100 * 1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
					log.error(e.getMessage());
				}
			}
		}
	}
}
